import java.io.DataOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.DateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.Hashtable;

import javax.swing.DefaultListModel;

public class Server {
	
	private ServerSocket ss;
	@SuppressWarnings("unchecked")
	private Hashtable outputStreams = new Hashtable();
	public static ckinUtils u = new ckinUtils();
	public boolean logging = true;
	Date now = new Date();
	DefaultListModel listModel = new DefaultListModel();
	
	public Server(int port) throws IOException {
		listen(port);
	}
	
	@SuppressWarnings("unchecked")
	private void listen(int port) throws IOException {
			
		ss = new ServerSocket(port);
		System.out.println("New server socket " + ss + " is running." );
		
		while (true) {
			Socket s = ss.accept();
			System.out.println(s + " connected.");
			DataOutputStream dout = new DataOutputStream(s.getOutputStream());
			outputStreams.put(s, dout);
			new ClientHandler(this, s);
		}
	}
	
	@SuppressWarnings("unchecked")
	Enumeration getOutputStreams() {
		return outputStreams.elements();
	}
	
	@SuppressWarnings("unchecked")
	void sendMessage(String user, String text) {
		synchronized(outputStreams) {
			for (Enumeration e = getOutputStreams(); e.hasMoreElements();) {
				DataOutputStream dout = (DataOutputStream)e.nextElement();
				try {
					dout.writeUTF("Talk|-|" + user + "[" + DateFormat.getTimeInstance(DateFormat.SHORT).format(now) + "]: " + text);
					if(logging)
						LogMsg(user, text);
				} catch(IOException ie) {
					System.out.println(ie);
				}
			}
		}
	}
	
	@SuppressWarnings("unchecked")
	public void sendClientUpdate(String client, boolean add){
		synchronized(outputStreams) {
			for (Enumeration e = getOutputStreams(); e.hasMoreElements();) {
				DataOutputStream dout = (DataOutputStream)e.nextElement();
				try {
					dout.writeUTF("clUpdate|-|" + client + "|-|" + add);
				} catch(IOException ie) {
					System.out.println(ie);
				}
			}
		}
	}
	
	void removeConnection(Socket s) {
		synchronized(outputStreams) {
			System.out.println(s + " disconnected.");
			outputStreams.remove(s);
			try {
				s.close();
			} catch(IOException ie) {
				System.out.println("Error closing "+s);
				ie.printStackTrace();
			}
		}
	}
	
	static public void main(String args[]) throws Exception {
		boolean waiting = true;
		String ans = null;
		while(waiting){
			ans = u.Input("Port:");
			if(!u.isStrInt(ans)){
				u.Msg("Invalid Port.");
			}
			else if(u.isStrInt(ans))
				waiting = false;
		}
		int port = Integer.parseInt(ans);
		new Server(port);
	}
	
	public void print(String user, String text) {
		System.out.println(user + "[" + DateFormat.getTimeInstance(DateFormat.SHORT).format(now) + "]: " + text);
	}
	
	private void LogMsg(String user, String m) {
		try {
			String temp = now.toString();
			String[] date = temp.split(" ");
			FileWriter outFile = new FileWriter("C:\\WiiTalk\\Logs\\" + date[0] + "_" + date[1] + "_"  + date[2] + ".txt", true);
			PrintWriter out = new PrintWriter(outFile);
			out.println(user + "[" + DateFormat.getTimeInstance(DateFormat.SHORT).format(now) + "]: " + m);
			out.close();
		} catch (IOException e){
			e.printStackTrace();
		}	
	}
}